package cn.onein.edu.web.controller;

import java.io.IOException;
import java.io.Writer;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.mortbay.util.ajax.JSON;
import org.mortbay.util.ajax.JSON.Convertor;
import org.mortbay.util.ajax.JSONObjectConvertor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import cn.onein.edu.biz.bean.Order;
import cn.onein.edu.biz.bean.SharedActions;
import cn.onein.edu.biz.bean.User;
import cn.onein.edu.biz.bean.UserDailyAction;
import cn.onein.edu.util.DateUtil;
import cn.onein.edu.web.common.base.BaseController;
import cn.onein.edu.web.jms.producer.SendMailProducer;
import cn.onein.edu.web.service.LearnService;
import cn.onein.edu.web.service.PaymentService;
import cn.onein.edu.web.service.UserCenterService;
import cn.onein.edu.web.util.AjaxCallBackJsonUtil;
import cn.onein.edu.web.util.CenterHotContentUtil;
import cn.onein.edu.web.vo.AjaxCallbackVO;
import cn.onein.edu.web.vo.DailyActionVO;
import cn.onein.edu.web.vo.ShareActionVO;

/**
 * 用户中心控制器
 * 
 * @author justin
 * 
 */
@Controller
public class UserCenterController extends BaseController {

	Logger logger = Logger.getLogger(UserCenterController.class);

	private static final String PREDAY = "preDay";

	private static final String PREWEEK = "preWeek";

	private static final String NEXTDAY = "nextDay";

	private static final String NEXTWEEK = "nextWeek";

	private static final String CURRENTDAY = "curDay";

	private static final String INPUTDAY = "inputDay";

	private static final String STRNULLACTIONRESULT = "爹哋，妈咪，今天 你们行动了么？宝宝好像和爹哋还有妈咪做游戏哟~~不要偷懒，宝宝在等你们的哟 ~~";

	private static final String STRACTIONRESULT = "亲爱的爸爸、妈妈，能不能为我写写日记呢？虽然宝宝还不会写字，但宝宝很想把你们为宝宝做的点点滴滴都记下来。等长大了，识字了，宝宝会......";

	private static final String STRTOMORROWDAILY = "爹哋，妈 咪，我们明天继续哟~~";

	private static final String MEMBERSTATUS = "MEMBERSTATUS";
	
	private static final String SUBDAYS = "SUBDAYS";

	@Autowired
	private UserCenterService userCenterService;

	@Autowired
	private SendMailProducer sendMailProducer;

	@Autowired
	private PaymentService paymentService;
	
	@Autowired
	private LearnService learnService;

	/**
	 * 用户中心首页
	 * 
	 * @return
	 */
	@RequestMapping(value = "/center", method = { RequestMethod.GET,
			RequestMethod.POST })
	public ModelAndView index(HttpServletResponse resp, HttpServletRequest req)
			throws Exception {
		Map<String, Object> param = new HashMap<String, Object>();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date nowDate = new Date();

		// 得到登录用户信息
		User user = this.getLoginUser(req);
		if (null == user) {
			return new ModelAndView("redirect:/login?type=redirect");
		}

		List<UserDailyAction> dailyActions = userCenterService
				.getDailyAction(user.getId());

		// 显示数据格式转换
		initUserCenterVO(dailyActions, param);

		List<Order> orderList = paymentService.getOrderByUserId(user.getId());
		if (user.getLevelExpires() == null || orderList == null || orderList.isEmpty()) {
			// 没有订单 或者过期时间为空
			param.put(MEMBERSTATUS, null);
		} else {
			//过期时间到现在间隔天数
			int days = DateUtil.daysOfTwo(new Date(), user.getLevelExpires());
			
			if (days > 15) {
				// 有效期大于15天 ---有效
				param.put(MEMBERSTATUS, Boolean.TRUE);
			} else {
				// 有效期小于15天 或者 已经过期 ---无效
				if (days > 0){
					param.put(SUBDAYS, days);
				}
				param.put(MEMBERSTATUS, Boolean.FALSE);
			}
		}
		
		//得到用户中心最新资讯文章
		CenterHotContentUtil.initHotContent(req, user, learnService, param);

		param.put("currDate", df.format(nowDate));
		param.put("user", user);

		setMenu(param, MENU_VALUE_PERSON_CENTER);

		return new ModelAndView("center/index", param);
	}
	
	/**
	 * 页面切换
	 * 
	 * @return
	 */
	@RequestMapping(value = "/service/changePage.json", method = {
			RequestMethod.GET, RequestMethod.POST })
	public void changePage(String type, String curDate,
			HttpServletResponse resp, HttpServletRequest req) throws Exception {
		Date currDate = null;
		List<UserDailyAction> dailyActions = new ArrayList<UserDailyAction>();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

		// 得到登录用户信息
		User user = this.getLoginUser(req);

		try {
			currDate = df.parse(curDate);
		} catch (Exception e) {
			logger.error("currentDate format error in changePage function", e);
			AjaxCallBackJsonUtil.callbackJSON(new AjaxCallbackVO(AJAXERROR),
					resp);
			return;
		}

		try {
			// 得到前三天数据
			if (PREDAY.equals(type)) {
				dailyActions = userCenterService.getPreDayDailyAction(
						user.getId(), currDate);
			}

			// 得到下三天数据
			if (NEXTDAY.equals(type)) {
				if (df.format(new Date()).compareTo(df.format(currDate)) > 0) {
					dailyActions = userCenterService.getNextDayDailyAction(
							user.getId(), currDate);
				}
			}

			// 得到上周数据
			if (PREWEEK.equals(type)) {
				dailyActions = userCenterService.getPreWeekDailyAction(
						user.getId(), currDate);
			}

			// 得到下周数据
			if (NEXTWEEK.equals(type)) {
				if (df.format(new Date()).compareTo(df.format(currDate)) > 0) {
					dailyActions = userCenterService.getNextWeekDailyAction(
							user.getId(), currDate);
				}
			}

			// 得到今天数据
			if (CURRENTDAY.equals(type)) {
				if (null != userCenterService.getDailyAction(user.getId(),
						df.format(new Date()))) {
					if (!df.format(new Date()).equals(df.format(currDate))) {
						dailyActions = userCenterService.getDailyAction(user
								.getId());
					}
				}
			}

			// 得到用户输入日期的数据
			if (INPUTDAY.equals(type)) {
				if (null != userCenterService.getDailyAction(user.getId(),
						df.format(currDate))) {
					if (df.format(DateUtil.getDateBydays(new Date(), 1))
							.compareTo(df.format(currDate)) >= 0) {
						dailyActions = userCenterService
								.getInputDayDailyAction(user.getId(), currDate);
					}
				}

			}
		} catch (Exception e) {
			logger.error("Find daily action error in change page function.", e);
			AjaxCallBackJsonUtil.callbackJSON(new AjaxCallbackVO(AJAXERROR),
					resp);
			return;
		}

		responseJSON(convertDailyActionVO(dailyActions), resp);
	}

	/**
	 * 保存成长日志
	 * 
	 * @return
	 */
	@RequestMapping(value = "/service/saveContent.json", method = {
			RequestMethod.GET, RequestMethod.POST })
	public void saveContent(String contentValue, String actionDate,
			String actionResult, HttpServletResponse resp,
			HttpServletRequest req) throws Exception {
		User user = this.getLoginUser(req);

		try {
			contentValue = URLDecoder.decode(contentValue, "UTF-8");
			userCenterService.insertBabyDaily(contentValue, user.getId(),
					actionDate, actionResult);
		} catch (Exception e) {
			logger.error("save baby daily error", e);
			AjaxCallBackJsonUtil.callbackJSON(new AjaxCallbackVO(AJAXERROR),
					resp);
			return;
		}

		AjaxCallBackJsonUtil
				.callbackJSON(new AjaxCallbackVO(AJAXSUCCESS), resp);
	}

	/**
	 * 将该文章分享朋友
	 * 
	 * @return
	 */
	@RequestMapping(value = "/service/shareContent.json", method = {
			RequestMethod.GET, RequestMethod.POST })
	public void shareContent(String actionDate, HttpServletResponse resp,
			HttpServletRequest req) throws Exception {
		String shareActionUrl = "";
		ShareActionVO vo = new ShareActionVO();

		User user = this.getLoginUser(req);

		try {
			SharedActions shareAction = userCenterService.insertShareAction(
					user.getId(), actionDate);
			shareActionUrl = req.getRequestURL().toString();
			shareActionUrl = shareActionUrl.replace(
					"service/shareContent.json",
					"share/" + shareAction.getUuid() + ".jhtml");
			vo.setUrl(shareActionUrl);
			vo.setShareBabyDaily(shareAction.getShareActionBaby());
		} catch (Exception e) {
			logger.error(
					"insert share action error in share content function.", e);
			AjaxCallBackJsonUtil.callbackJSON(new AjaxCallbackVO(AJAXERROR),
					resp);
			return;
		}

		shareBabyDailyJSON(vo, resp);
	}

	/**
	 * 将该文章分享朋友
	 * 
	 * @return
	 */
	@RequestMapping(value = "/service/shareBabydaily.json", method = {
			RequestMethod.GET, RequestMethod.POST })
	public void shareBabyDaily(String shareBabyDaily, String actionDate,
			HttpServletResponse resp, HttpServletRequest req) throws Exception {

		User user = this.getLoginUser(req);

		try {
			userCenterService.updateShareAction(user.getId(), actionDate,
					shareBabyDaily);
		} catch (Exception e) {
			logger.error("update error in updateShareAction.", e);
			AjaxCallBackJsonUtil.callbackJSON(new AjaxCallbackVO(AJAXERROR),
					resp);
			return;
		}

		AjaxCallBackJsonUtil
				.callbackJSON(new AjaxCallbackVO(AJAXSUCCESS), resp);
	}

	/**
	 * 将该文章分享朋友
	 * 
	 * @return
	 */
	@RequestMapping(value = "/service/sendMail.json", method = {
			RequestMethod.GET, RequestMethod.POST })
	public void sendMail(String emails, String shareUrl,
			HttpServletResponse resp, HttpServletRequest req) throws Exception {

		if (null == emails || "".equals(emails)) {
			return;
		}

		String[] mailArray = emails.split(";");
		for (String mail : mailArray) {
			try {
				if (mail != null && mail.trim().length() > 0) {
					 sendMailProducer.sendShareActionMailMessage(mail.trim(), shareUrl);
				}
			} catch (Exception e) {
				logger.error("send mail fail: " + mail, e);
				AjaxCallBackJsonUtil.callbackJSON(
						new AjaxCallbackVO(AJAXERROR), resp);
				return;
			}
		}

		AjaxCallBackJsonUtil
				.callbackJSON(new AjaxCallbackVO(AJAXSUCCESS), resp);
	}

	/**
	 * 数据格式化输出
	 * 
	 * @param dailyActions
	 * @return
	 */
	private List<DailyActionVO> convertDailyActionVO(
			List<UserDailyAction> dailyActions) {
		List<DailyActionVO> vos = new ArrayList<DailyActionVO>();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

		for (UserDailyAction o : dailyActions) {
			DailyActionVO vo = new DailyActionVO();
			vo.setIntroText(o.getIntroText());
			if (o.getActive()) {
				vo.setFullText(o.getFullText());
			}
			Date actionDate = o.getActionDate();
			String strDate = df.format(actionDate);
			vo.setDate(strDate.substring(5, 10));
			vo.setWeek(DateUtil.getWeekOfDate(actionDate));
			vo.setDailyNote(o.getDailyNote());
			vo.setActionDate(df.format(o.getActionDate()));
			if (df.format(DateUtil.getDateBydays(new Date(), 1)).equals(
					df.format(o.getActionDate()))) {
				vo.setBabyDaily(STRTOMORROWDAILY);
				vo.setBabyDailyNull(null);
			} else if (null == o.getBabyDaily() || "".equals(o.getBabyDaily())) {
				vo.setBabyDaily(STRACTIONRESULT);
				if (df.format(new Date()).equals(df.format(o.getActionDate()))) {
					if (null == o.getActionResult() || 0 == o.getActionResult()) {
						vo.setBabyDaily(STRNULLACTIONRESULT);
					}
				}
				vo.setBabyDailyNull(Boolean.TRUE);
			} else {
				vo.setBabyDaily(o.getBabyDaily());
				vo.setBabyDailyNull(Boolean.FALSE);
			}
			vo.setActionResult(o.getActionResult());
			vos.add(vo);
		}
		return vos;
	}

	private void initUserCenterVO(List<UserDailyAction> dailyActions,
			Map<String, Object> param) {
		int flag = 0;
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

		// 格式化数据输出
		for (UserDailyAction o : dailyActions) {
			DailyActionVO vo = new DailyActionVO();
			vo.setIntroText(o.getIntroText());
			if (o.getActive()) {
				vo.setFullText(o.getFullText());
			}
			Date actionDate = o.getActionDate();
			String strDate = df.format(actionDate);
			vo.setDate(strDate.substring(5, 10));
			vo.setWeek(DateUtil.getWeekOfDate(actionDate));
			vo.setDailyNote(o.getDailyNote());
			vo.setActionDate(df.format(o.getActionDate()));

			if (df.format(DateUtil.getDateBydays(new Date(), 1)).equals(
					df.format(o.getActionDate()))) {
				vo.setBabyDaily(STRTOMORROWDAILY);
				vo.setBabyDailyNull(null);
			} else if (null == o.getBabyDaily() || "".equals(o.getBabyDaily())) {
				vo.setBabyDaily(STRACTIONRESULT);
				if (df.format(new Date()).equals(df.format(o.getActionDate()))) {
					if (null == o.getActionResult() || 0 == o.getActionResult()) {
						vo.setBabyDaily(STRNULLACTIONRESULT);
					}
				}
				vo.setBabyDailyNull(Boolean.TRUE);
			} else {
				vo.setBabyDaily(o.getBabyDaily());
				vo.setBabyDailyNull(Boolean.FALSE);
			}

			vo.setActionResult(o.getActionResult());
			if (flag == 0) {
				param.put("preDayAction", vo);
			} else if (flag == 1) {
				param.put("curDayAction", vo);
			} else if (flag == 2) {
				param.put("nextDayAction", vo);
			}
			flag++;
		}
	}

	/**
	 * 将对象转化为JSON字符串
	 * 
	 * @param vos
	 * @param resp
	 * @throws IOException
	 */
	private void responseJSON(List<DailyActionVO> vos, HttpServletResponse resp)
			throws IOException {
		Convertor convertor = new JSONObjectConvertor();
		JSON.registerConvertor(List.class, convertor);
		JSON.registerConvertor(DailyActionVO.class, convertor);
		resp.setContentType("text/json; charset=utf-8");
		Writer w = resp.getWriter();
		w.write(JSON.toString(vos));
		w.close();
	}

	/**
	 * 将对象转化为JSON字符串
	 * 
	 * @param vos
	 * @param resp
	 * @throws IOException
	 */
	private void shareBabyDailyJSON(ShareActionVO vo, HttpServletResponse resp)
			throws IOException {
		Convertor convertor = new JSONObjectConvertor();
		JSON.registerConvertor(ShareActionVO.class, convertor);
		resp.setContentType("text/json; charset=utf-8");
		Writer w = resp.getWriter();
		w.write(JSON.toString(vo));
		w.close();
	}

}
